from __future__ import annotations
from base.ship_enum import AffinityLevel
from .default_value import DEFAULT_STATE
from .enhancement import Enhancement
from .limit_break import LimitBreak
from .retrofit import Retrofit
from base.observer_pattern import Subject


class ShipState(Subject):
    def __init__(self, affinity: int = DEFAULT_STATE['affinity'], oath: bool = DEFAULT_STATE['oath'],
                 morale: int = DEFAULT_STATE['morale'], level: int = DEFAULT_STATE['level'],
                 enhancement: Enhancement = None, limit_break: LimitBreak = None, retrofit: Retrofit = None):
        """
        舰船状态信息, 保存舰船的可变属性
        :param affinity: 好感度
        :param oath: 誓约状态
        :param morale: 心情
        :param level: 等级
        :param enhancement: 强化信息
        :param limit_break: 突破信息
        :param retrofit: 改造信息
        """
        super().__init__()
        self._affinity: int = affinity if 0 <= affinity <= 200 else 100
        self._oath: bool = oath if self._affinity == 100 else True if self._affinity > 100 else False
        self._morale: int = morale if 0 <= morale <= 150 else 150
        self._level: int = level if 0 < level <= 125 else 120
        self._enhancement: Enhancement = enhancement
        if self._enhancement is not None:
            self.register_observer(enhancement)
        self._limit_break: LimitBreak = limit_break
        if self._limit_break is not None:
            self.register_observer(limit_break)
        self._retrofit: Retrofit = retrofit
        if self.breakthrough_grade != 3 and self._retrofit.flag_allowed:
            self._retrofit.flag_enable = False

    @property
    def affinity(self):
        """好感度"""
        return self._affinity

    @affinity.setter
    def affinity(self, value: int):
        """好感度设置范围为0~200, 设定值大于100时, 会修改誓约状态为真, 设定值小于100时, 会修改誓约状态为假"""
        self._oath = bool(value > 100)
        if value < 100:
            self._oath = False
            self._affinity = max(0, value)
        elif value > 100:
            self._oath = True
            self._affinity = min(value, 200)
        else:
            self._affinity = value

    @property
    def affinity_level(self) -> AffinityLevel:
        """好感度等级"""
        if self._affinity == 200:
            return AffinityLevel.MAX
        elif self._affinity >= 100 and self._oath:
            return AffinityLevel.OATH
        elif self._affinity == 100 and not self._oath:
            return AffinityLevel.LOVE
        elif self._affinity > 80:
            return AffinityLevel.CRUSH
        elif self._affinity > 60:
            return AffinityLevel.FRIENDLY
        elif self._affinity > 30:
            return AffinityLevel.STRANGER
        else:
            return AffinityLevel.UPSET

    @property
    def oath(self) -> bool:
        """誓约状态"""
        return self._oath

    @oath.setter
    def oath(self, value: bool):
        """誓约状态设置为True时好感度小于100, 或设置为False时好感度大于100, 会将好感度置为100"""
        if (value and self._affinity < 100) or (not value and self._affinity > 100):
            self._affinity = 100
        self._oath = value

    @property
    def morale(self) -> int:
        """心情"""
        return self._morale

    @morale.setter
    def morale(self, value: int):
        """心情设置范围为0~150"""
        self._morale = max(0, min(value, 150))

    @property
    def level(self) -> int:
        """等级"""
        return self._level

    @level.setter
    def level(self, value: int):
        """等级设置范围为1~125, 如果设定的等级与突破等级不匹配, 会相应修改突破等级"""
        self._level = max(1, min(value, 125))
        if self._level > 100:
            self._limit_break.breakthrough_grade = 3
        elif self._level < 10 and self._limit_break.breakthrough_grade > 0:
            self._limit_break.breakthrough_grade = 0
        elif self._level < 30 and self._limit_break.breakthrough_grade > 1:
            self._limit_break.breakthrough_grade = 1
        elif self._level < 70 and self._limit_break.breakthrough_grade > 2:
            self._limit_break.breakthrough_grade = 2
        self.notify_observers()

    @property
    def enhancement(self) -> Enhancement:
        """强化信息, 会返回一个强化信息的实例"""
        return self._enhancement

    @enhancement.setter
    def enhancement(self, value: Enhancement):
        """设置强化信息, 会同时将自身传递给强化信息的状态属性"""
        if value is None:
            return
        if self._enhancement is None:
            self._enhancement = value
            self.register_observer(value)

    @property
    def enhancement_enable(self) -> bool:
        """是否启用强化"""
        return self._enhancement.flag_enable

    @enhancement_enable.setter
    def enhancement_enable(self, value):
        self._enhancement.flag_enable = value

    @property
    def enhancement_set(self) -> bool:
        """是否允许设置强化数值"""
        return self._enhancement.flag_set

    @enhancement_set.setter
    def enhancement_set(self, value: bool):
        self._enhancement.flag_set = value

    @property
    def enhancement_value(self) -> tuple[int, int, int, int]:
        """
        强化数值
        :return: 返回炮击/雷击/航空/装填强化数值的四元组
        """
        return self._enhancement.fp, self._enhancement.trp, self._enhancement.avi, self._enhancement.rld

    @enhancement_value.setter
    def enhancement_value(self, value: tuple[int, int, int, int]):
        """
        设置强化数值, 接收炮击/雷击/航空/装填的四元组
        """
        self._enhancement.set_all_enhancement_value(value)

    @property
    def limit_break(self) -> LimitBreak:
        """突破信息, 会返回一个突破信息的实例"""
        return self._limit_break

    @limit_break.setter
    def limit_break(self, value: LimitBreak):
        if value is None:
            return
        if self._limit_break is None:
            self._limit_break = value
            self.register_observer(value)

    @property
    def breakthrough_grade(self) -> int:
        return self.limit_break.breakthrough_grade

    @breakthrough_grade.setter
    def breakthrough_grade(self, value):
        """设置突破等级, 如果舰船等级不满足突破要求, 会调整舰船等级到满足突破要求的最近等级"""
        if value == 3 and self._level < 70:
            self.level = 70
        elif value == 2 and self._level < 30:
            self.level = 30
        elif value == 1 and self._level < 10:
            self.level = 10
        elif value == 0 and self._level > 100:
            self.level = 100

    @property
    def retrofit(self) -> Retrofit:
        """改造信息, 会返回一个改造信息的实例"""
        return self._retrofit

    @retrofit.setter
    def retrofit(self, value: Retrofit):
        """改造信息为None时, 可以设置改造信息实例, 设置后不可更改"""
        if value is None:
            return
        if self._retrofit is None:
            self._retrofit = value
            if self.breakthrough_grade != 3:
                self.retrofit_enable = False

    @property
    def retrofit_enable(self):
        """是否启用改造"""
        return self._retrofit.flag_enable

    @retrofit_enable.setter
    def retrofit_enable(self, value):
        """设置是否启用改造, 目前只允许满破舰船选择启用, 且只能满改"""
        if self.breakthrough_grade == 3:
            self.retrofit.flag_enable = value
        else:
            self.retrofit.flag_enable = False
